#pragma once

#include "log.hpp"
#include "nocopy.hpp"
#include <sys/epoll.h>

#define event_in EPOLLIN
#define event_out EPOLLOUT

// epoll_create epoll_wait epoll_ctl
// EPOLL_CTL_ADD EPOLL_CTL_MOD EPOLL_CTL_DEL
class epoller: public nocopy
{
public:
    epoller()
    {}

    void Init()
    {
        _epfd = epoll_create(1);
    }

    void epoll_status(int sock, int op, uint32_t event)
    {
        struct epoll_event ee;
        ee.data.fd = sock;
        if(op == EPOLL_CTL_DEL)
        {
            int n = epoll_ctl(_epfd, op, sock, nullptr);
            close(ee.data.fd);
            if(n < 0) lg(Warning, "epoll_ctl DEL Error: %s, errno: %d", strerror(errno), errno);
        }
        else
        {
            ee.events = event;
            int n = epoll_ctl(_epfd, op, sock, &ee);
            if(n < 0) lg(Warning, "epoll_ctl ADD|MOD Error: %s, errno: %d", strerror(errno), errno);
        }
    }

    int epoll_Take(struct epoll_event* ep)
    {
        int n = epoll_wait(_epfd, ep, 1024, _timeout);
        return n;
    }

    ~epoller()
    {}
private:
    int _epfd;
    int _timeout = 3000;
};